package RSA;

import org.apache.commons.codec.binary.Base64;


import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Map;

import static RSA.RsaSignature.*;


/**
 * @author WuYongheng
 * @date 2023/3/6
 * @description
 */
public class Test {

    /**
     * 数字签名密钥算法
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 数字签名
     * 签名/验证算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    //公钥 Map Key
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //私钥Map key
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * RSA密钥长度，默认1024位，密钥长度必须是64的倍数，范围512～65536位之间
     */
    private static final int KEY_SIZE = 512;

    public static byte[] sign(byte[] data, byte[] privateKey) throws Exception {
        //转换私钥材料
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKey);
        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //取私钥对象
        PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initSign(priKey);
        //更新
        signature.update(data);
        //签名
        return signature.sign();
    }

    public static boolean verity(byte[] data, byte[] publicKey, byte[] sign) throws  Exception{
        //转换公钥材料
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        //实例化密钥工厂
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        //生成公钥
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        //实例化Signature
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        //初始化Signature
        signature.initVerify(pubKey);
        //更新
        signature.update(data);
        //校验证
        return signature.verify(sign);
    }

    public void rsaSignTest() throws Exception {
        //初始化密钥
        Map<String, Object> keyMap = initKey();
        byte[] publicKey = getPublicKey(keyMap);
        byte[] privateKey = getPrivateKey(keyMap);
        System.out.println("私钥："+Base64.encodeBase64String(privateKey));
        System.out.println ("公钥："+Base64.encodeBase64String(publicKey));

        String inputStr = "0000070ef55f59e0b938a7666d1355c6717090f511a9efab8a0fcd9fadcd2372";
        System.out.println("签名前："+inputStr);
        byte[] data = inputStr.getBytes();
        //产生签名
        byte[] sign = sign(data, privateKey);
        System.out.println("签名："+ Base64.encodeBase64String(sign));
        //验证签名
        boolean status = verity(data, publicKey, sign);
        System.out.println("验签状态："+ status);
    }

    public static void main(String[] args) {
        Test t=new Test();
        try {
            t.rsaSignTest();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
